package com.ninespace.springboot.autoconfigure.mybatis;

import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
import java.io.IOException;

@Configuration
//@Import(value = {MyBatisDataSourceProperties.class,MyBatisProperties.class})
@EnableConfigurationProperties(value = {MyBatisDataSourceProperties.class,MyBatisProperties.class})
@ConditionalOnClass(value = {SqlSessionFactory.class,MyBatisDataSourceProperties.class,MyBatisProperties.class})
public class MyBatisAutoConfiguration {

    /**
     * 资源加载类：
     * 1.classpath前缀只能获取当前类路径下的资源文件,使用方法resolver.getResource(path)获取
     * 2.classpath*前缀可以获取所有类路径下的资源文件，包括jar包中的。使用方法resolver.getResources(path)获取
     * */
    /*@Autowired
    private ResourcePatternResolver resourcePatResolver;*/

    /*数据源配置*/
    @Bean
    public DataSource druidDataSource(MyBatisDataSourceProperties myBatisDataSourceProperties){
        DruidDataSource druidDataSource=new DruidDataSource();
        druidDataSource.setDriverClassName(myBatisDataSourceProperties.getDriverClassName());
        druidDataSource.setUrl(myBatisDataSourceProperties.getUrl());
        druidDataSource.setUsername(myBatisDataSourceProperties.getUsername());
        druidDataSource.setPassword(myBatisDataSourceProperties.getPassword());
        return druidDataSource;
    }

    /**
     * mybatis会话工厂配置
     * */
    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource,MyBatisProperties myBatisProperties) throws IOException {
        SqlSessionFactoryBean sqlSessionFactoryBean=new SqlSessionFactoryBean();
        PathMatchingResourcePatternResolver resolver= new PathMatchingResourcePatternResolver();
        sqlSessionFactoryBean.setDataSource(dataSource);
        String clsPathPrefix=PathMatchingResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX;
        sqlSessionFactoryBean.setMapperLocations(resolver.getResources(clsPathPrefix+myBatisProperties.getMapperLocations()));
        sqlSessionFactoryBean.setConfigLocation(resolver.getResources(clsPathPrefix+myBatisProperties.getConfigLocation())[0]);
        return sqlSessionFactoryBean;
    }

    /**
     * mybatis包扫描,不在此配置，会导致过早实例化，建议具体项目中使用MapperScan注解配置
     * 关注：实现BeanDefinitionRegistryPostProcessor接口的类会在spring对类增强（类属性的读取配置等）之前实例化，所以导致属性值无法注入
     * */
    /*@Bean
    public MapperScannerConfigurer mapperScannerCongigurer(MyBatisProperties myBatisProperties){
        MapperScannerConfigurer mapperScannerConfigurer=new MapperScannerConfigurer();
        mapperScannerConfigurer.setBasePackage(myBatisProperties.getBasePackage());
        mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactoryBean");
        return mapperScannerConfigurer;
    }*/

    /*事务管理器*/
    @Bean
    public DataSourceTransactionManager dataSourceTransactionManager(DataSource dataSource){
        DataSourceTransactionManager dataSourceTransactionManager=new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(dataSource);
        return dataSourceTransactionManager;
    }

    @Bean
    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

}
